package br.ucb.ucblive.managedbean;

import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import javax.faces.application.ViewHandler;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.imageio.ImageIO;

import org.primefaces.model.DefaultStreamedContent;
import org.primefaces.model.StreamedContent;
import org.primefaces.model.UploadedFile;

import br.ucb.ucblive.HIB.AlunoHIB;
import br.ucb.ucblive.HIB.AutorizacaoHIB;
import br.ucb.ucblive.HIB.ModeradorHIB;
import br.ucb.ucblive.HIB.ProfessorHIB;
import br.ucb.ucblive.HIB.UsuarioHIB;
import br.ucb.ucblive.beans.Usuario;
import br.ucb.ucblive.recursos.Functions;
import br.ucb.ucblive.recursos.MensagemConfirmacao;

@ManagedBean(name="usuarioManagedBean")
@SessionScoped
public class UsuarioManagedBean {
	private Usuario usuario;
	private Usuario buscaUsuario;
	private List<Usuario> usuarios;
	private ModeradorManagedBean moderadorManagedBean;
	private ProfessorManagedBean professorManagedBean;
	private AlunoManagedBean alunoManagedBean;
	private UsuarioHIB usuarioHIB;
	private ModeradorHIB moderadorHIB = new ModeradorHIB();
	private ProfessorHIB professorHIB = new ProfessorHIB();
	private AlunoHIB alunoHIB = new AlunoHIB();
	private boolean biUsuario;
	private String query;
	private Usuario usuarioLogin;
	private UploadedFile arquivo;
	private MensagemConfirmacao mensagemConfirmacao;
	private boolean usuarioAlterada;
	
	public UsuarioManagedBean(){
		setUsuario(new Usuario());
		setUsuarios(new ArrayList<Usuario>());
		setModeradorManagedBean(new ModeradorManagedBean());
		setProfessorManagedBean(new ProfessorManagedBean());
		setAlunoManagedBean(new AlunoManagedBean());
		setUsuarioHIB(new UsuarioHIB());
		setUsuarios(new ArrayList<Usuario>());
		setBiUsuario(false);
		setQuery(new String());
		setMensagemConfirmacao(new MensagemConfirmacao());
		setUsuarioLogin(usuarioHIB.consultar(FacesContext.getCurrentInstance().getExternalContext().getUserPrincipal().getName()));
		setUsuarioAlterada(false);
	}

	
	public boolean isUsuarioAlterada() {
		return usuarioAlterada;
	}


	public void setUsuarioAlterada(boolean usuarioAlterada) {
		this.usuarioAlterada = usuarioAlterada;
	}


	public ModeradorHIB getModeradorHIB() {
		return moderadorHIB;
	}


	public void setModeradorHIB(ModeradorHIB moderadorHIB) {
		this.moderadorHIB = moderadorHIB;
	}


	public ProfessorHIB getProfessorHIB() {
		return professorHIB;
	}


	public void setProfessorHIB(ProfessorHIB professorHIB) {
		this.professorHIB = professorHIB;
	}


	public AlunoHIB getAlunoHIB() {
		return alunoHIB;
	}


	public void setAlunoHIB(AlunoHIB alunoHIB) {
		this.alunoHIB = alunoHIB;
	}


	public MensagemConfirmacao getMensagemConfirmacao() {
		return mensagemConfirmacao;
	}


	public void setMensagemConfirmacao(MensagemConfirmacao mensagemConfirmacao) {
		this.mensagemConfirmacao = mensagemConfirmacao;
	}


	public Usuario getUsuario() {
		return usuario;
	}

	public void setUsuario(Usuario usuario) {
		this.usuario = usuario;
	}

	public Usuario getBuscaUsuario() {
		return buscaUsuario;
	}
	
	public void setBuscaUsuario(Usuario buscaUsuario) {
		this.buscaUsuario = buscaUsuario;
	}
	
	public List<Usuario> getUsuarios() {
		return usuarios;
	}

	public void setUsuarios(List<Usuario> usuarios) {
		this.usuarios = usuarios;
	}

	public ModeradorManagedBean getModeradorManagedBean() {
		return moderadorManagedBean;
	}

	public void setModeradorManagedBean(ModeradorManagedBean moderadorManagedBean) {
		this.moderadorManagedBean = moderadorManagedBean;
	}
	
	public ProfessorManagedBean getProfessorManagedBean() {
		return professorManagedBean;
	}


	public void setProfessorManagedBean(ProfessorManagedBean professorManagedBean) {
		this.professorManagedBean = professorManagedBean;
	}


	public AlunoManagedBean getAlunoManagedBean() {
		return alunoManagedBean;
	}


	public void setAlunoManagedBean(AlunoManagedBean alunoManagedBean) {
		this.alunoManagedBean = alunoManagedBean;
	}

	public UsuarioHIB getUsuarioHIB() {
		return usuarioHIB;
	}


	public void setUsuarioHIB(UsuarioHIB usuarioHIB) {
		this.usuarioHIB = usuarioHIB;
	}
	
	public boolean isBiUsuario() {
		return biUsuario;
	}


	public void setBiUsuario(boolean biUsuario) {
		this.biUsuario = biUsuario;
	}
	
	public String getQuery() {
		return query;
	}

	public void setQuery(String query) {
		this.query = query;
	}
	

	public Usuario getUsuarioLogin() {
		return usuarioLogin;
	}


	public void setUsuarioLogin(Usuario usuarioLogin) {
		this.usuarioLogin = usuarioLogin;
	}

	public UploadedFile getArquivo() {
		return arquivo;
	}


	public void setArquivo(UploadedFile arquivo) {
		this.arquivo = arquivo;
	}


	/**
	 * M�todo que insere um usu�rio no banco
	 * @return
	 * @throws Throwable 
	 */
	public String insere(){
		String url;
		usuarioHIB.salvar(usuario);
		
		AutorizacaoHIB autorizacaoHib = new AutorizacaoHIB();
		
		switch (getUsuario().getTipo()){
			case 1:	if(!isUsuarioAlterada()) getMensagemConfirmacao().moderadorCriado(); 
					else  getMensagemConfirmacao().moderadorAlterado();
				    getModeradorManagedBean().insere(getUsuario());
					if(!biUsuario){
						autorizacaoHib.salvarModerador(getUsuario());
					}
					
					url = "index.jsf"; 
					break;
			case 2:if(!isUsuarioAlterada()) getMensagemConfirmacao().professorCriado(); 
					else  getMensagemConfirmacao().professorAlterado();
				    getProfessorManagedBean().insere(getUsuario());
					if(!biUsuario){
		            	autorizacaoHib.salvarProfessor(getUsuario());
					}
					url = "index.jsf";	
					break;
			case 3:if(!isUsuarioAlterada()) getMensagemConfirmacao().alunoCriado(); 
					else  getMensagemConfirmacao().alunoAlterado(); 
				    getAlunoManagedBean().insere(getUsuario());
					if(!biUsuario){
						autorizacaoHib.salvarAluno(getUsuario());
					}
					
					url = "index.jsf"; 
					break;
			default: 
					url = "index.jsf";
		}
		setUsuario(new Usuario());
		setBiUsuario(false);
		setUsuarioAlterada(false);
		url = "index.jsf";
		return url;
	}
	
	public String atualiza() throws SQLException{
		if(buscaUsuario!=null){
			switch (buscaUsuario.getTipo()) {
				case 1: moderadorManagedBean.setModerador(moderadorHIB.consultarByLogin(buscaUsuario.getLogin()));
						if(moderadorManagedBean.getModerador().getCurso()==null)
							getModeradorManagedBean().populaCursos(false,0);
						else
							getModeradorManagedBean().populaCursos(true,moderadorManagedBean.getModerador().getCurso().getIdCurso());
						break;
		
				case 2: professorManagedBean.setProfessor(professorHIB.consultarByLogin(buscaUsuario.getLogin()));
						break;
					
				case 3: alunoManagedBean.setAluno(alunoHIB.consultarByLogin(buscaUsuario.getLogin()));
						getAlunoManagedBean().populaCursos();
						break;
			}
			getMensagemConfirmacao().alunoExcluido();
		}
		setUsuario(buscaUsuario);
		setBiUsuario(true);
		setBuscaUsuario(new Usuario());
		setQuery(new String());
		setUsuarioAlterada(true);
		return "/alu/usuarioForm?faces-redirect=true";
	}
	
	public void excluir(ActionEvent evento){
		buscaUsuario = (Usuario) evento.getComponent().getAttributes().get("usuario");
		usuarioHIB.excluir(buscaUsuario);
		setBuscaUsuario(new Usuario());
		setUsuarios(new ArrayList<Usuario>());
		switch (getUsuario().getTipo()){
			case 1:	getMensagemConfirmacao().moderadorExcluido();
					break;
			case 2: getMensagemConfirmacao().professorExcluido();
					break;
			case 3: getMensagemConfirmacao().alunoExcluido();
					break;
			
		}
	}
	
	/**
	 * M�todo que retorna uma lista de usu�rios
	 * @param query
	 * @return
	 */
	public String listarUsuarios(){
		setUsuarios(new ArrayList<Usuario>());
		List<Usuario> users = new ArrayList<Usuario>();
		for(Usuario u : usuarioHIB.listar()) {  
            if(u.getLogin().toUpperCase().startsWith(query.toUpperCase()) && u.getTipo()!=4)
                users.add(u);  
        }  		
		usuarios.addAll(users);
		setQuery(new String());
		return "/adm/usuarioList?faces-redirect=true";
	}
	
	/**
	 * M�todo que popula tudo que for preciso
	 * @return
	 * @throws SQLException
	 */
	public String populaAll() throws SQLException{
		setUsuario(new Usuario());
		setBuscaUsuario(new Usuario());
		setModeradorManagedBean(new ModeradorManagedBean());
		setProfessorManagedBean(new ProfessorManagedBean());
		setAlunoManagedBean(new AlunoManagedBean());
		getModeradorManagedBean().populaCursos(false,0);
		getAlunoManagedBean().populaCursos();
		setBiUsuario(false);
		return "/alu/usuarioForm?faces-redirect=true";
	}
	
	public String usuarioPerfil(){
		switch (getUsuarioLogin().getTipo()) {
			case 1: moderadorManagedBean.setModerador(moderadorHIB.consultarByLogin(usuarioLogin.getLogin()));
			try {
				moderadorManagedBean.populaCursosModerador(usuarioLogin);
			} catch (SQLException e) {
				e.printStackTrace();
			}
				break;
	
			case 2: professorManagedBean.setProfessor(professorHIB.consultarByLogin(usuarioLogin.getLogin()));
			try {
				professorManagedBean.populaDisciplinaProfessor(usuarioLogin);
			} catch (SQLException e) {
				e.printStackTrace();
			}
					break;
				
			case 3: alunoManagedBean.setAluno(alunoHIB.consultarByLogin(usuarioLogin.getLogin()));
			try {
				alunoManagedBean.populaCursosAluno(usuarioLogin);
				alunoManagedBean.populaDisciplinaAluno(usuarioLogin);
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
				break;
		}
		
		return "/alu/perfilView?faces-redirect=true";
	}
	
	public void upload() {  
		if(usuarioLogin.getTipo()!=4)	
			if(arquivo!=null)
				usuario.setFotoPerfil(arquivo.getContents());
    }
	
	
	/**
	 * Metodo: Adionar pontos de warn ao usuario da postagem
	 */
	public void adicionaWarns(ActionEvent evento){
		setUsuario(new Usuario());
			
		usuario = (Usuario) evento.getComponent().getAttributes().get("usuario");
		usuario.setQtdWarns(usuario.getQtdWarns()+1);
		
		switch(usuario.getQtdWarns()){
		
			case 3: usuario.setStatus(1);
					usuario.setDataAcesso(Functions.adicionarDiasData(1));
					break;
					
				
			case 4: usuario.setStatus(1);
					usuario.setDataAcesso(Functions.adicionarDiasData(3));
					break;
				
			case 5: usuario.setStatus(1);
					usuario.setDataAcesso(Functions.adicionarDiasData(15));
					break;
				
			case 6:	usuario.setStatus(1);
					usuario.setDataAcesso(Functions.adicionarDiasData(30));
					break;
				
			case 7: usuario.setStatus(2);
					usuario.setDataAcesso(null);
					default: break;
		
		}

		usuarioHIB.salvar(usuario);
			
	}
	
	public void limpaWarns(ActionEvent evento){
		setUsuario(new Usuario());
		usuario = (Usuario) evento.getComponent().getAttributes().get("usuario");
		usuario.setQtdWarns(0);
		usuario.setStatus(0);
		usuario.setDataAcesso(null);
		usuarioHIB.salvar(usuario);
	}
	
	public void subtraiWarns(ActionEvent evento){
		setUsuario(new Usuario());
		usuario = (Usuario) evento.getComponent().getAttributes().get("usuario");
		usuario.setQtdWarns(usuario.getQtdWarns()-1);
		
		switch(usuario.getQtdWarns()){
		
			case 1: usuario.setStatus(0);
					usuario.setDataAcesso(null);
					break;
					
			case 2: usuario.setStatus(0);
					usuario.setDataAcesso(null);
					break;
					
			case 3: usuario.setStatus(1);
					usuario.setDataAcesso(Functions.subtrairDiasData(usuario.getDataAcesso(),2));
					break;
					
			case 4: usuario.setStatus(1);
					usuario.setDataAcesso(Functions.subtrairDiasData(usuario.getDataAcesso(),12));
					break;
				
			case 5: usuario.setStatus(1);
					usuario.setDataAcesso(Functions.subtrairDiasData(usuario.getDataAcesso(),15));
					break;
				
			case 6:	usuario.setStatus(1);
					usuario.setDataAcesso(Functions.adicionarDiasData(30));
					break;
		}
		
		usuarioHIB.salvar(usuario);
	}
	
	
	
}
